﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace UFIDA.U9.WSS.ProxyService.Utils
{
    /// <summary>
    ///     数据保护帮助类
    /// </summary>
    public static class DataProtector
    {
        /// <summary>
        ///     获取二进制Key
        ///     key值必须是8位64个字节
        /// </summary>
        /// <param name="keyString"></param>
        /// <returns></returns>
        private static byte[] GetByteKey(string keyString)
        {
            if (string.IsNullOrEmpty(keyString)) return null;
            if (keyString.Length < 8)
            {
                while (true)
                {
                    if (keyString.Length >= 8)
                        break;
                    keyString += keyString;
                }
            }

            keyString = keyString.Substring(0, 8);
            return Encoding.Unicode.GetBytes(keyString);
        }

        /// <summary>
        ///     加密
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="dataToEncrypt"></param>
        /// <returns></returns>
        public static string Encrypt(string privateKey, string dataToEncrypt)
        {
            return string.IsNullOrEmpty(privateKey) ? dataToEncrypt : Encrypt(GetByteKey(privateKey), dataToEncrypt);
        }

        /// <summary>
        ///     加密
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="dataToEncrypt"></param>
        /// <returns></returns>
        public static string Encrypt(byte[] privateKey, string dataToEncrypt)
        {
            if (privateKey == null || privateKey.Length == 0) return dataToEncrypt;
            if (string.IsNullOrEmpty(dataToEncrypt)) return string.Empty;
            using (Rijndael rijndael = Rijndael.Create())
            {
                rijndael.Key = privateKey;
                rijndael.IV = privateKey;
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(),
                        CryptoStreamMode.Write))
                    {
                        using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                        {
                            streamWriter.Write(dataToEncrypt);
                            streamWriter.Flush();
                            cryptoStream.FlushFinalBlock();
                            byte[] inArray = memoryStream.ToArray();
                            return Convert.ToBase64String(inArray);
                        }
                    }
                }
            }
        }

        /// <summary>
        ///     解密
        /// </summary>
        /// <param name="encryptKey"></param>
        /// <param name="encryptedData"></param>
        /// <returns></returns>
        public static string Decrypt(string encryptKey, string encryptedData)
        {
            return string.IsNullOrEmpty(encryptKey) ? encryptedData : Decrypt(GetByteKey(encryptKey), encryptedData);
        }

        /// <summary>
        ///     解密
        /// </summary>
        /// <param name="encryptKey"></param>
        /// <param name="encryptedData"></param>
        /// <returns></returns>
        public static string Decrypt(byte[] encryptKey, string encryptedData)
        {
            if (encryptKey == null || encryptKey.Length == 0) return encryptedData;
            if (string.IsNullOrEmpty(encryptedData)) return string.Empty;
            using (Rijndael rijndael = Rijndael.Create())
            {
                rijndael.Key = encryptKey;
                rijndael.IV = encryptKey;
                byte[] buffer = Convert.FromBase64String(encryptedData);
                using (MemoryStream memoryStream = new MemoryStream(buffer))
                {
                    using (CryptoStream cryptoStream =
                        new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        using (StreamReader streamReader = new StreamReader(cryptoStream))
                        {
                            return streamReader.ReadToEnd();
                        }
                    }
                }
            }
        }
    }
}